package com.caissa.springboot.starter.permission.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.caissa.ecp.base.api.common.exception.CommonRuntimeException;
import com.caissa.ecp.base.api.dto.po.PermissionPo;
import com.caissa.ecp.base.api.dto.po.UserInfo;
import com.base.springboot.starter.permission.domain.AccountInfo;
import com.base.springboot.starter.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * B端 账户及权限
 *
 * @author yuzhongbo
 * @date 2020/5/20
 */
@Slf4j
public class PermissionService {
    @Autowired
    private RedisService redisService;

    /**
     * 用户权限
     */
    public static final String REDIS_PREFIX_USER_PERMISSION = "acc_user_permission_";

    /**
     * 用户信息
     */
    public static final String REDIS_PREFIX_ACC_USER = "acc_user_";

    /**
     * 获取登录用户信息
     *
     * @return
     */
    public AccountInfo getLoginAccountInfo() {
        HttpServletRequest request = getHttpServletRequest();
        AccountInfo userInfo = new AccountInfo();

        Map<String, Object> userInfoMap = getUserInfoMap(request);
        Object id = userInfoMap.get(TokenConstant.xId);
        Object bySystem = userInfoMap.get(TokenConstant.xBtSystem);

        if (id != null) {
            userInfo.setId(new Long(id.toString()));
        }

        String redisKey = PermissionService.REDIS_PREFIX_ACC_USER + id;
        AccountInfo accountInfo = (AccountInfo) redisService.get(redisKey);
        if (ObjectUtil.isNull(accountInfo)) {
            throw new CommonRuntimeException("获取用户详情异常, id: " + id);
        }
        userInfo = accountInfo;

        if (bySystem != null) {
            userInfo.setBtSystem(bySystem.toString());
        }
        userInfo.setDataPermission(getDataPermission());
        return userInfo;
    }

    /**
     * 从request 获取用户信息
     *
     * @param request
     * @return
     */
    private Map<String, Object> getUserInfoMap(HttpServletRequest request) {
        Map<String, Object> userInfoMap = new HashMap<>(8);
        String token = request.getHeader(TokenConstant.xToken);
        String userId = request.getHeader(TokenConstant.xId);

        if (StrUtil.isBlank(userId) && StrUtil.isNotBlank(token)) {
            JSONObject userJsonObject = AesTokenUtil.getUserJsonObject(token);

            userInfoMap.put(TokenConstant.xId, userJsonObject.get(TokenConstant.id));
            userInfoMap.put(TokenConstant.xBtSystem, userJsonObject.get(TokenConstant.btSystem));
        } else {
            userInfoMap.put(TokenConstant.xId, request.getHeader(TokenConstant.xId));
            userInfoMap.put(TokenConstant.xBtSystem, request.getHeader(TokenConstant.xBtSystem));
        }
        return userInfoMap;
    }

    /**
     * 获取登录用户信息
     *
     * @return
     */
    public UserInfo getLoginUserInfo() {
        UserInfo userInfo = new UserInfo();
        AccountInfo accountInfo = getLoginAccountInfo();
        BeanUtil.copyProperties(accountInfo, userInfo);
        return userInfo;
    }

    /**
     * 获取数据权限
     *
     * @return
     */
    public String getDataPermission() {
        HttpServletRequest request = getHttpServletRequest();
        String permissionKey = request.getHeader(TokenConstant.permissionKey);

        Map<String, Object> userInfoMap = getUserInfoMap(request);
        Object userId = userInfoMap.get(TokenConstant.xId);
        Object bySystem = userInfoMap.get(TokenConstant.xBtSystem);

        if (userId != null && StrUtil.isNotBlank(permissionKey)) {
            String redisKey = PermissionService.REDIS_PREFIX_USER_PERMISSION + bySystem + "_" + userId;
            Map<Long, PermissionPo> permissionPos = (Map<Long, PermissionPo>) redisService.get(redisKey);
            PermissionPo permissionPo = permissionPos.get(permissionKey);
            if (permissionPo != null && permissionPo.getDataPermission() != null && StrUtil.isNotBlank(permissionPo.getDataPermission().getPermissionKey())) {
                return permissionPo.getDataPermission().getPermissionKey();
            } else {
                return "0";
            }
        } else {
            return "0";
        }
    }

    /**
     * 获取HttpServletRequest
     *
     * @return
     */
    private HttpServletRequest getHttpServletRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
        return attributes.getRequest();
    }
}
